/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ces31.ChineseDicesServer.RN;

import java.rmi.RemoteException;
import java.util.List;
import java.util.Random;
import ces31.ChineseDicesCommon.ClienteInterface;
import ces31.ChineseDicesServer.IP.IP_Ranking;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Imada
 */
public class RN_Jogo {

    public RN_Jogo(List<RN_Jogador> players) {
        this.jogadores = players;
        //inicializarJogadores();
       // iniciarJogo();
    }

    /**
     * Give up and finalize game
     * -> Finalize game
     * @param quitterClient
     */
    public void finalizarJogoPorDesistencia(ClienteInterface quitterClient) {
        definirVencedorDoJogo(quitterClient);
        finalizarJogo();
    }

    public void definirVencedorDoJogo(ClienteInterface clienteDesistente) {
        RN_Jogador quitter = getJogadores().get(0);
        if (getJogadores().get(1).getClienteInterface().equals(clienteDesistente)) {
            quitter = getJogadores().get(1);
        }
        definirJogadorQueIraIniciarRodada(outroJogador(quitter));
    }

    /**
     * Inform clients that the game is over and updates the ranking.
     * -> Collaborations:
     * [VF1]finalize
     */
    public void finalizarJogo() {
        for (int i = 0; i < getJogadores().size(); i++) {
            try {
                getJogadores().get(i).getClienteInterface().apresentarResultadoDoJogo(vencedor.getNome());
            } catch (RemoteException ex) {
                Logger.getLogger(RN_Jogo.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        atualizarRanking();
        for (RN_Jogador jogador : getJogadores()) {
            RN_SalaDeEspera.instanciaDe().desconectarJogador(jogador.getNome());
        }
    }

    public void finalizarRodada() {
        definirJogadorQueIraIniciarRodada(getRodada().verificarVencedorDaRodada());
        if (isFinished()) {
            finalizarJogo();
        } else {
            iniciarRodada();
        }
    }


    private RN_Jogador outroJogador(RN_Jogador player) {
        if (player.equals(getJogadores().get(0))) {
            return getJogadores().get(1);
        }
        return getJogadores().get(0);
    }

    private boolean isFinished() {
        for (int i = 0; i < getJogadores().size(); i++) {
            if (getJogadores().get(i).getQuantidadeDeDados() == 0) {
                setPrimeiroAJogar(outroJogador(getJogadores().get(i)));
                return true;
            }
        }
        return false;
    }

    /**
     * -> Initialize jogadores
     * -> Set first player (variable vencedor)
     * -> Start Round
     * -> Collaborations:
     * [VF1]iniciarJogo
     *
     */
    public void montarTabuleiro() {
        for (int i = 0; i < getJogadores().size(); i++) {
            try {
                RN_Jogador player = getJogadores().get(i);
//        for(Player player : getJogadores()){
//            try{
                player.getClienteInterface().iniciarJogo(player.getNome(), outroJogador(player).getNome());
            } catch (RemoteException ex) {
                Logger.getLogger(RN_Jogo.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        Random generator = new Random();
        definirJogadorQueIraIniciarRodada(getJogadores().get(generator.nextInt(1)));
        iniciarRodada();
    }

    public void iniciarRodada() {
        try {
            setRodada(new RN_Rodada(this, jogadores, vencedor));
            getRodada().iniciarRodada();
        } catch (RemoteException ex) {
            Logger.getLogger(RN_Jogo.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void atualizarRanking() {
        IP_Ranking.getInstance().atualizarRanking(vencedor.getNome());
    }

    /* Getters and Setters*/
    public void inicializarJogadores() {
        for (RN_Jogador jogador : this.jogadores) {
            jogador.anexarDados();
        }
        montarTabuleiro();
    }

    public List<RN_Jogador> getJogadores() {
        return this.jogadores;
    }

    public RN_Jogador getPrimeiroAJogar() {
        return primeiroAJogar;
    }

    private void setPrimeiroAJogar(RN_Jogador starter) {
        this.primeiroAJogar = starter;
    }

    public RN_Rodada getRodada() {
        return rodada;
    }

    private void setRodada(RN_Rodada round) {
        this.rodada = round;
    }

    public RN_Jogador getVencedor() {
        return vencedor;
    }

    public void definirJogadorQueIraIniciarRodada(RN_Jogador winner) {
        this.vencedor = winner;
    }



    private RN_Jogador vencedor;
    private List<RN_Jogador> jogadores;
    private RN_Rodada rodada;
    private RN_Jogador primeiroAJogar;
}
